import tools from "../tools"

export default class Conn extends Element {
    constructor() {
        super()
        document.on("toggle-conn-list", data => {
            this.isShowConnList = data.data
            this.componentUpdate()
        })
        document.on("refresh", () => {
            this.fetchConnects()
        })

        tools.bindGlobalEvt("sqlite-init", evt => {
            this.fetchConnects()
        })
    }

    isShowConnList = true
    /**
     * 连接列表
     * @type {[]}
     */
    list = []

    /**
     * 连接信息
     * @type {{dbs: string, id: string}}
     */
    connectData = {}
    /**
     * 数据库信息
     * @type {{}}
     */
    databaseInfo = {}

    /**
     * 渲染完成事件
     */
    componentDidMount() {
        this.fetchConnects()
    }

    /**
     * 获取连接列表
     */
    fetchConnects() {
        this.list = tools.getView().xcall("query_conn", "")
        this.componentUpdate()
    }


    /**
     * 渲染列表
     * @returns {unknown[]}
     */
    renderList() {
        if (this.list.length < 1) {
            return <div class={"none"}>{tools.lang("main.connectList.none")}</div>
        }
        return this.list.map((e, i) =>
            <div class={"list-item"} onClick={() => this.itemClick(e, i)}>
                {this.renderItem(e)}
                {this.connectData.id === e.id ? <div class={"list-item-connected"}>on</div> : ""}
            </div>
        )
    }

    /**
     * 渲染每一行
     * @param data {object} 每一行的数据
     * @returns {JSX.Element}
     */
    renderItem(data) {
        return <div class="toggle-item">
            <div class={data.open === true ? "title open" : "title"}>
                <div class={"title-name"}><i class={"icon icon-lan-pending"}></i> <span
                    style={"display:inline-block;padding:2px;"}></span> <span>{data.name}</span></div>
                {this.renderArrow(data)}
            </div>
            {this.renderOpen(data)}
        </div>
    }

    /**
     * 改变箭头状态
     * @param data {object} 每一行的数据
     * @returns {JSX.Element}
     */
    renderArrow(data) {
        if (data.open !== true) {
            return <span class="icon icon-menu-down"></span>
        }
        return <span class="icon icon-menu-up"></span>
    }

    /**
     * 编辑连接
     * @param evt {Event} sciter Event
     * @param ele {Element} 当前element
     * @param data {Object} 当前这一行的数据
     */
    editConnect(evt, ele, data) {
        this.dialog("编辑连接", data)
            .then(res => {
                if (res && res.code === 1) {
                    this.fetchConnects()
                }
            })
    }

    /**
     * 删除连接
     * @param evt {Event} sciter Event
     * @param ele {Element} 当前element
     * @param data {Object} 当前这一行的数据
     */
    deleteConnect(evt, ele, data) {
        tools.confirm("删除过后无法恢复，确定要删除吗?")
            .then(res => {
                if (res === true) {
                    if (tools.getView().xcall("delete_conn", data.id) === true) {
                        tools.alert("删除成功！", {type: "success"})
                            .then(res => {
                                this.fetchConnects()
                            })
                        document.post(new Event("delete-conn", {bubbles: true, data: {id: data.id}}))
                        return
                    }
                    tools.alert("删除失败！", {type: "error"})
                }
            })
    }

    /**
     * 重置初始化数据
     */
    resetInitData() {
        this.connectData = {}
        this.databaseInfo = {}
        this.componentUpdate()
        document.post(new Event("redis-close", {bubbles: true}))
    }

    /**
     * 连接redis
     * @param evt {Event} sciter Event
     * @param ele {Element} 当前element
     * @param data {Object} 当前这一行的数据
     */
    connectRedis(evt, ele, data) {
        // id相同关闭
        if (this.connectData.id === data.id) {
            this.resetInitData()
            return
        }
        // 连接redis
        // let res = tools.getView().xcall("connect_redis", data)
        tools.loading.show()
        tools.getView().xcall("async_connect_redis", data, status => {
            if (status === true) {
                document.post(new Event("redis-open", {
                    bubbles: true,
                    data: {info: this.getRedisInfo(data), id: data.id}
                }))
                this.componentUpdate()
            } else {
                tools.alert("redis连接失败", {})
            }
            tools.loading.hide()
        })

    }

    /**
     * 获取redis信息
     * @returns {{}}
     */
    getRedisInfo(data) {
        let cfg = tools.getView().xcall("get_redis_info")
        if (!cfg) return
        let tmp = {}
        cfg.split("#").map(e => e.split("\r\n").filter(v => v !== ""))
            .forEach(e => {
                if (e[0] == undefined) {
                    return
                }
                try {
                    let key = e[0].replaceAll(" ", "")
                    tmp[key] = {}
                    e.slice(1).forEach(item => {
                        let data = item.split(":")
                        if (data[1].indexOf(",") > -1) {
                            let child = data[1].split(",")
                            let map = {}
                            child.map(val => {
                                let s = val.split("=")
                                map[s[0]] = s[1]
                            })
                            tmp[key][data[0]] = map
                            return
                        }
                        if (data[1].indexOf("=") > -1) {
                            let v = data[1].split("=")
                            tmp[key][data[0]] = {[v[0]]: v[1]}
                            return
                        }
                        tmp[key][data[0]] = data[1]
                    })
                } catch (e) {
                    tools.log(e.message)
                }

            })
        let dbs = tools.getView().xcall("get_redis_dbs")
        this.connectData = Object.assign({}, data)
        this.connectData.dbs = dbs
        this.connectData.db = 0
        this.databaseInfo = tmp
        window.databaseInfo = tmp
        return tmp
    }

    /**
     * 渲染点击的打开事件
     * @param data {object} 当前这一行的数据
     * @returns {JSX.Element|string}
     */
    renderOpen(data) {
        if (data.open !== true) {
            return ""
        }
        return <div class="folder-open" onClick={evt => evt.stopPropagation()}>
            <div class={"folder-action"}>
                <div
                    class={"edit ac-btn btn btn-primary"}
                    onClick={(...args) => this.editConnect(...args, data)}>
                    编辑
                </div>
                <div
                    class={"delete ac-btn btn btn-primary"}
                    onClick={(...args) => this.deleteConnect(...args, data)}>
                    删除
                </div>
                <div class={"connect ac-btn btn btn-primary"}
                     onClick={(...args) => this.connectRedis(...args, data)}>
                    {data.id === this.connectData.id ? "断开" : "连接"}
                </div>
            </div>
            <div class={"db-list"}>
                {this.renderDatabaseList(data)}
            </div>
        </div>
    }

    /**
     * 连接redis的某个数据库
     * @param evt {Event} sciter Event
     * @param ele {Element} 当前element
     * @param index {number} 数据库
     */
    connectDB(evt, ele, index) {
        this.connectData.db = "" + index
        let res = tools.getView().xcall("connect_redis", this.connectData)
        if (res === true) {
            document.post(new Event("db-change", {bubbles: true, data: {db: this.connectData.db}}))
            this.componentUpdate()
        } else {
            tools.alert("连接失败", {type: "error"})
            this.componentUpdate()
        }
    }

    /**
     * 渲染redis数据库
     * @param data
     * @returns {[]}
     */
    renderDatabaseList(data) {
        if (data.id === this.connectData.id) {

            return new Array(Number(this.connectData.dbs)).fill(0).map((_, i) => {
                return <div class={"" + this.connectData.db === "" + i ? "db-item db-connected" : "db-item"}
                            onClick={(...args) => this.connectDB(...args, i)}>
                    <i class={"icon icon-database db-icon"}></i>
                    数据库 {i}
                </div>
            })
        }
        return []
    }

    /**
     * 当前行的点击事件
     * @param data {object} 当前行的数据
     * @param index {number} 当前行的索引
     */
    itemClick(data, index) {
        // 实现百叶窗开关特效
        this.list.forEach((item, i) => {
            if (i != index) {
                this.list[i]["open"] = false
            }
        })
        this.componentUpdate()
        try {
            this.list[index]["open"] = !this.list[index]["open"]
        } catch (e) {

        }
        this.componentUpdate()
    }

    /**
     * 编辑连接弹框
     * @param title 弹框标题
     * @param data {object} 当前行数据
     * @returns {Promise<Window>} 窗口指针
     */
    dialog(title, data) {
        return new Promise(resolve => {
            setTimeout(() => {
                let [x, y] = tools.windowPosition()
                let [w, h] = tools.windowSize()
                let scale = devicePixelRatio
                let width = 520 * scale
                let height = 420 * scale
                let win = tools.getView().modal({
                    width,
                    height,
                    x: x + w / 2 - width  / 2,
                    y: y + h / 2 - height / 2,
                    url: "/sqlite/maintain_conn.html",
                    parameters: {
                        title: title,
                        view: tools.getView(),
                        data
                    }
                })
                resolve(win)
            })
        })

    }

    /**
     * 添加按钮点击事件
     * @param evt {Event} sciter Event
     * @param ele {Element} 当前dom元素
     */
    ["on click at #add"](evt, ele) {
        this.dialog("新建连接")
            .then(res => {
                if (res && res.code === 1) {
                    this.fetchConnects()
                }
            })
    }

    /**
     * 渲染
     * @returns {JSX.Element}
     */
    render() {
        return <div class="connection-list" style={this.isShowConnList === false ? "width:0;overflow:hidden;" : ""}>
            <div class="add">
                <div id="add" class="btn btn-primary" style="width:75%">
                    <span class="icon icon-plus"></span> {tools.lang("main.connectList.addBtn")}
                </div>
            </div>
            <div class="c-list">
                {this.renderList()}
            </div>
        </div>
    }
}